package com.hexacta.hrs.web.struts.actions.projects;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;
import org.springframework.util.StringUtils;
import org.vectrics.employee.Employee;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.user.Person;
import org.vectrics.user.User;

import com.hexacta.hrs.domain.exchange.Accrued;
import com.hexacta.hrs.domain.exchange.Confirmation;
import com.hexacta.hrs.domain.staffing.Project;
import com.hexacta.hrs.service.staffing.ClientService;
import com.hexacta.hrs.service.staffing.ProjectService;
import com.hexacta.hrs.services.employee.EmployeeService;
import com.hexacta.hrs.services.exchange.AccruedService;
import com.opensymphony.xwork2.ActionSupport;

public class AccrualAction extends ActionSupport implements SessionAware, ServletRequestAware{

	private static final long serialVersionUID = 1L;
	
	private EmployeeService employeeService;
	private ClientService clientService;
	private ProjectService projectService;
	private AccruedService accruedService;
	
	private HttpServletRequest request;
	@SuppressWarnings("rawtypes")
	private Map session;
	
	private String chargedAccueds;
	private String selectedProjectId;
	private String selectedProjectName;
	
	private List<Accrued> accruedList = new ArrayList<Accrued>();
	
	public String filterAccruals(){
		this.setAccruedList(getAccruedList());
		return SUCCESS;
	}
	
	public String save() {
		Integer position = chargedAccueds.indexOf(";");
		Integer begin = 0;
		
		Double totalEarn = 0d;
		Double totalBill = 0d;
		
		List<Accrued> accrueds = new ArrayList<Accrued>();
		List<Confirmation> confirmations = new ArrayList<Confirmation>();
		while (position != -1) {
			String accruedString = chargedAccueds.substring(begin, position);
			
			try {
				begin = 0;
				Integer endIndex = accruedString.indexOf(",");
				Integer year = Integer.valueOf(accruedString.substring(begin,endIndex));
				begin = endIndex + 1;
				endIndex = accruedString.indexOf(",", endIndex + 1);
				Integer month = Integer.valueOf(accruedString.substring(begin,
						endIndex));

				begin = endIndex + 1;
				endIndex = accruedString.indexOf(",", endIndex + 1);
				Double earn = Double.valueOf(accruedString.substring(begin,
						endIndex));

				begin = endIndex + 1;
				endIndex = accruedString.indexOf(",", endIndex + 1);
				Double bill = Double.valueOf(accruedString.substring(begin,
						endIndex));

				begin = endIndex + 1;
				endIndex = accruedString.indexOf(",", endIndex + 1);
				boolean estimated = Boolean.parseBoolean(accruedString
						.substring(begin, endIndex));

				begin = endIndex + 1;
				endIndex = accruedString.indexOf(",", endIndex + 1);
				String comment = accruedString.substring(begin, endIndex);

				begin = endIndex + 1;
				endIndex = accruedString.indexOf(",", endIndex + 1);
				String userId = accruedString.substring(begin, endIndex);


				Accrued accrued = new Accrued();
				accrued.setYear(year);
				accrued.setMonth(month);
				accrued.setEarn(earn);
				accrued.setBill(bill);
				accrued.setEstimated(estimated);
				accrued.setComment(comment);

				if (!userId.equalsIgnoreCase("undefined")) {
					User user = CoreServiceLocator.getUserService()
							.getUserById(Long.parseLong(userId));

					Employee employee = employeeService.searchBy(user);
					begin = endIndex + 1;

					Calendar date = Calendar.getInstance();
					date.setTimeInMillis(Long.valueOf(accruedString
							.substring(begin)));

					Confirmation confirmation = new Confirmation();
					confirmation.setUser(employee);
					confirmation.setDate(date);

					accrued.setConfirmation(confirmation);
					confirmations.add(confirmation);
				}
				
				begin = position + 1;
				position = chargedAccueds.indexOf(";", position + 1);
				
				totalEarn += earn;
				totalBill += bill;
				
				accrueds.add(accrued);
			} catch (Exception e) {
				return INPUT;
			}
		}
		
		if ((totalEarn - totalBill) != 0.0) {
			addActionError("The ammount of the earn and bill are not the same");
			return INPUT;
		}
		
		Project project = projectService.searchById(Long.valueOf(selectedProjectId));
		
		for (Confirmation confirmation : confirmations) {
			accruedService.saveConfirmation(confirmation);
		}
		
		project.addAccruedList(accrueds);
		projectService.save(project);
		
		return SUCCESS;
	}
	
	
	public String getLoggedUser(){
		Person person = CoreServiceLocator.getUserAuthService().getAuthorizedPerson(getSession());
		return person.getUser().getUserName();
	}
	
	public Long getLoggedUserId(){
		Person person = CoreServiceLocator.getUserAuthService().getAuthorizedPerson(getSession());
		return person.getUser().getId();
	}
	
	public List<Project> getAllProjectsList() {
		return (List<Project>) this.getProjectService().findAll();
	}
	
	@SuppressWarnings("unchecked")
	public List<Accrued> getAccruedList() {
		if(selectedProjectId != null){
			Set<Accrued> accruedSet = projectService.searchById(Long.valueOf(selectedProjectId)).getAccrueds();
			if(accruedSet.size() != 0){
				return new ArrayList<Accrued>(accruedSet);
			}else{
				return new ArrayList<Accrued>();
			}
			
		}else{
			return new ArrayList<Accrued>();
		}
	}

	public void setAccruedList(List<Accrued> accruedList) {
		this.accruedList = accruedList;
	}
	
	//Parameters
	
	public String getSelectedProjectId() {
		return selectedProjectId;
	}

	public void setSelectedProjectId(String selectedProjectId) {
		this.selectedProjectId = selectedProjectId;
	}

	public String getSelectedProjectName() {
		return selectedProjectName;
	}

	public void setSelectedProjectName(String selectedProjectName) {
		this.selectedProjectName = selectedProjectName;
	}

	public String getChargedAccueds() {
		return chargedAccueds;
	}

	public void setChargedAccueds(String chargedAccueds) {
		this.chargedAccueds = chargedAccueds;
	}

	//Services
	
	public EmployeeService getEmployeeService() {
		return employeeService;
	}

	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}

	public ClientService getClientService() {
		return clientService;
	}

	public void setClientService(ClientService clientService) {
		this.clientService = clientService;
	}
	
	public ProjectService getProjectService() {
		return projectService;
	}

	public void setProjectService(ProjectService projectService) {
		this.projectService = projectService;
	}

	public AccruedService getAccruedService() {
		return accruedService;
	}

	public void setAccruedService(AccruedService accruedService) {
		this.accruedService = accruedService;
	}

	public Map getSession() {
		return session;
	}

	public void setSession(Map session) {
		this.session = session;
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request; 
	}

	public HttpServletRequest getRequest() {
		return request;
	}
	
}
